home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 223_01 / fscanf.c < prev    next >
Text File  |  1980-01-01  |  3KB  |  91 lines

  1. #define NOCCARGC  /* no argument count passing */
  2. /*
  3. ** Yes, that is correct.  Although these functions use an
  4. ** argument count, they do not call functions which need one.
  5. */
  6. #include stdio.h
  7.  
  8. static char *carg, *ctl, *unsigned;
  9. static int  *narg, wast, ac, width, ch, cnv, base, ovfl, sign;
  10.  
  11. /*
  12. ** fscanf(fd, ctlstring, arg, arg, ...) - Formatted read.
  13. ** Operates as described by Kernighan & Ritchie.
  14. ** b, c, d, o, s, u, and x specifications are supported.
  15. ** Note: b (binary) is a non-standard extension.
  16. */
  17. fscanf(argc) int argc; {
  18.   int *nxtarg;
  19.   nxtarg = CCARGC() + &argc;
  20.   return (Uscan(*(--nxtarg), --nxtarg));
  21.   }
  22.  
  23. /*
  24. ** scanf(ctlstring, arg, arg, ...) - Formatted read.
  25. ** Operates as described by Kernighan & Ritchie.
  26. ** b, c, d, o, s, u, and x specifications are supported.
  27. ** Note: b (binary) is a non-standard extension.
  28. */
  29. scanf(argc) int argc; {
  30.   return (Uscan(stdin, CCARGC() + &argc - 1));
  31.   }
  32.  
  33. /*
  34. ** Uscan(fd, ctlstring, arg, arg, ...) - Formatted read.
  35. ** Called by fscanf() and scanf().
  36. */
  37. Uscan(fd,nxtarg) int fd, *nxtarg; {
  38.   ac = 0;
  39.   ctl = *nxtarg--;
  40.   while(*ctl) {
  41.     if(isspace(*ctl)) {++ctl; continue;}
  42.     if(*ctl++ != '%') continue;
  43.     if(*ctl == '*') {narg = carg = &wast; ++ctl;}
  44.     else             narg = carg = *nxtarg--;
  45.     ctl += utoi(ctl, &width);
  46.     if(!width) width = 32767;
  47.     if(!(cnv = *ctl++)) break;
  48.     while(isspace(ch = fgetc(fd))) ;
  49.     if(ch == EOF) {if(ac) break; else return(EOF);}
  50.     ungetc(ch,fd);
  51.     switch(cnv) {
  52.       case 'c':
  53.         *carg = fgetc(fd);
  54.         break;
  55.       case 's':
  56.         while(width--) {
  57.           if((*carg = fgetc(fd)) == EOF) break;
  58.           if(isspace(*carg)) break;
  59.           if(carg != &wast) ++carg;
  60.           }
  61.         *carg = 0;
  62.         break;
  63.       default:
  64.         switch(cnv) {
  65.           case 'b': base =  2; sign = 1; ovfl = 32767; break;
  66.           case 'd': base = 10; sign = 0; ovfl =  3276; break;
  67.           case 'o': base =  8; sign = 1; ovfl =  8191; break;
  68.           case 'u': base = 10; sign = 1; ovfl =  6553; break;
  69.           case 'x': base = 16; sign = 1; ovfl =  4095; break;
  70.           default:  return (ac);
  71.           }
  72.         *narg = unsigned = 0;
  73.         while(width-- && !isspace(ch=fgetc(fd)) && ch!=EOF) {
  74.           if(!sign)
  75.             if(ch == '-') {sign = -1; continue;}
  76.             else sign = 1;
  77.           if(ch < '0') return (ac);
  78.           if(ch >= 'a')      ch -= 87;
  79.           else if(ch >= 'A') ch -= 55;
  80.           else               ch -= '0';
  81.           if(ch >= base || unsigned > ovfl) return (ac);
  82.           unsigned = unsigned * base + ch;
  83.           }
  84.         *narg = sign * unsigned;
  85.       }
  86.     ++ac;                          
  87.     }
  88.   return (ac);
  89.   }
  90.  
  91.